﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using Corona.TagContract;
using Corona.TagToolkit.Exception;
namespace Corona.TagToolkit
{
    public partial class AppSupport<T>:IDisposable
    {
        public Resource<T>[] getResources(IEnumerable<string> locaziers)
        {
            string[] loc = locaziers.ToArray<string>();
            Resource<T>[] res = new Resource<T>[loc.Length];
            for (int i = 0; i < res.Length; i++)
                res[i] = new Resource<T>(loc[i]);
            return res;
        }
        #region 对外暴露的常用操作接口

        /// <summary>
        /// 根据Query获取相应的资源
        /// </summary>
        /// <param name="query">查询类</param>
        /// <returns>资源的Locazier组</returns>
        public List<string> Search(Query query)
        {
            if (serverSupport == null || serverSupport.Server == null)
                throw new AppSupportNotReadyException("You can't use the public methods before create the AppSupport");
            if (query == null)
                return null;
            long[] uids = serverSupport.Server.Search(query.ToString());
            List<string> resourceLocaziers = new List<string>();
            foreach(long uid in uids)
                    resourceLocaziers.AddRange(database.GetLocazier(uid));
            return resourceLocaziers;
        }
        /// <summary>
        /// 封装的简易方法，根据一个tag找Resource
        /// </summary>
        /// <param name="tag"></param>
        /// <returns></returns>
        public List<string> Search(Tag tag)
        {
            if (tag == null)
                return null;
            Dictionary<Tag, long[]> dict = new Dictionary<Tag, long[]>();
            dict.Add(tag, new long[]{ 1, 1 });

            Query query = QueryFactory.CreateQuery(dict, 1);
            return Search(query);
        }
        public List<string> Search(string tagvalue)
        {
            Tag tag = new Tag(weaklink.Keys.ToArray()[0],tagvalue);
            Dictionary<Tag, long[]> dict = new Dictionary<Tag, long[]>();
            dict.Add(tag, new long[2] { 0, 1 });

            Query query = QueryFactory.CreateQuery(dict, 1);
            return Search(query);
        }

        public void RemoveTag(Resource<T> target, Tag tag)
        {
            int resault = this.serverSupport.Server.RemoveTag(target.uid, tag, verify.ToString());
            if (resault == 0)
                throw new AppVerifyFailedException();
            else if (resault == -1)
                throw new ServerException("Server Resisted on RemoveTag");
            
        }

        public void Update(Resource<T> resource, IEnumerable<Tag> tags)
        {
            if (resource != null)
                if (resource.State == ResourceState.Controlled)
                {
                    int resault = this.serverSupport.Server.Update(resource.uid, ServerSupport.convertTags(tags), verify.ToString());
                    if (resault == 0)
                        throw new AppVerifyFailedException();
                    else if (resault == -1)
                        throw new ServerException("Server throw Exception on Update");
                    
                }
        }

        public IEnumerable<Tag> GetTags(Resource<T> resource)
        {
            if (resource.State == ResourceState.Controlled)
            {

                XmlDocument richDiscription = new XmlDocument();
                richDiscription.LoadXml(serverSupport.Server.GetXmlByUID(resource.uid, weaklink.Keys.ToArray<string>()));

                XmlNode root = richDiscription.SelectSingleNode("/richdescription");
                foreach (XmlNode node in root)
                {
                    if (node.Name == "tag")
                    {
                        Tag tag = new Tag();
                        tag.Name = node.Attributes["name"].Value;
                        tag.Value = node.InnerText;
                        yield return tag;
                    }
                }
            }
            else throw new ResourceNotExtendsException();
            //TODO
 
        }//本地数据库中查找uid，利用UID获取tag 

        public TagJar GetTagJar(TagJar tagjar, double relevance)
        {//提交一堆,返回大于相关度的
            //分析TagJar当中的相似度关系，外部的是和整个参数相关的相似度关系

            if (tagjar == null)
                return null;
            return TagJar.convert(serverSupport.Server.GetTagJar(tagjar, relevance));
            
        }
        #endregion


        public static void setConfigPath(string path)
        {
            PrepareInfo<T>.configFile = path;
        }

        #region IDisposable Members

        public void Dispose()
        {
            serverSupport.shutdown();
            database.Close();
            GC.SuppressFinalize(this);
        }

        #endregion
    }


}
